import java.awt.*;
import java.awt.event.*;
import java.awt.FileDialog;
import java.awt.FlowLayout;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.*;

import javax.swing.*;
import javax.swing.event.*;

class Option{final static int PLAY=0,PAUSE=1,STOP=2,CIRCLE=3,OPEN=4;}

public class MediaPlayer implements ActionListener{
    JFrame f;
    JPanel p;
    JButton buttonPlay, buttonPause, buttonStop, buttonCircle, buttonOpen;
    JSlider sldTime, sldVolume;
    FileDialog flg;
    AudioInputStream audioInputStream;
    AudioFormat audioFormat;
    Clip myClip;
    File file;
    final String strCmd[]={"buttonPlay","buttonPause","buttonStop","buttonCircle","buttonOpen"};
    String filePath=""; 
    Thread myThread;
    double fileLength=0.0, lengthPerSecond=0.0;
    int totalSeconds=0, soundMinutes=0, soundSeconds=0;	//讀取到的wav檔案播放時間長度
    int playMinutes=0, playSeconds=0, playTotalSecs=0;	//正在播放的時間資訊
    FloatControl gainControl;		//­音量控制
    
    
    public static void main(String [] arg)
    {
        new MediaPlayer();
    }
    
    public  void AudioLoad()
    {
        filePath = flg.getDirectory()+flg.getFile();
        f.setTitle(filePath);
        if (myClip != null)
            myClip.close();
        myClip = null;
        audioInputStream = null;
        file = null;
        audioFormat = null;
        file = new File(filePath);
        try {
            audioInputStream = AudioSystem.getAudioInputStream(file);
            
            //取得這個.wav檔案的播放時間長度(總共幾秒和"分:秒"的格式)
            fileLength = audioInputStream.getFrameLength();
            lengthPerSecond = audioInputStream.getFormat().getSampleRate();
            totalSeconds = (int) (fileLength/lengthPerSecond);
            soundMinutes = totalSeconds/60;
            soundSeconds = totalSeconds%60;
            
            //取得現在播放進度(playTotalSecs=撥放了幾秒，playMinutes、playSeconds為 "分:秒"的格式)
            playTotalSecs = (int) (sldTime.getValue()/ audioInputStream.getFormat().getSampleRate());
            playMinutes = playTotalSecs/60;
            playSeconds = playTotalSecs%60;
            
            sldTime.setBorder(BorderFactory.createTitledBorder(playMinutes+":"+playSeconds+" / "+soundMinutes+":"+soundSeconds));
        } catch (UnsupportedAudioFileException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        audioFormat = audioInputStream.getFormat();
        DataLine.Info info = new DataLine.Info(Clip.class, audioFormat);
        try {
            myClip  = (Clip) AudioSystem.getLine(info);
            myClip.open(audioInputStream);
            
            //取得音量控制
            gainControl = (FloatControl) myClip.getControl(FloatControl.Type.MASTER_GAIN);
        } catch (LineUnavailableException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        } catch (IOException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }
    }
     
    public MediaPlayer()
    {
    	//播放時間  顯示、設定
    	sldTime = new JSlider(0,100,0);
    	sldTime.setBorder(BorderFactory.createTitledBorder("0:0 / 0:0"));
    	sldTime.addChangeListener(new ChangeListener(){
    	    public void stateChanged(ChangeEvent e)
    	    {
    	        if ((JSlider)e.getSource() == sldTime ){
    	        	if((myClip.getFramePosition() > sldTime.getValue()+audioFormat.getSampleRate()) || myClip.getFramePosition() < sldTime.getValue()){
                      myClip.setFramePosition(sldTime.getValue());
    	        		
                      //取得目前已經播放的秒數和對應的"分:秒"格式
                      playTotalSecs = (int) (sldTime.getValue()/ audioInputStream.getFormat().getSampleRate());
    	                playMinutes = playTotalSecs/60;
    	                playSeconds = playTotalSecs%60;
    	                //顯示 「播放時間」/「總共時間」
    	                sldTime.setBorder(BorderFactory.createTitledBorder(playMinutes+":"+playSeconds+" / "+soundMinutes+":"+soundSeconds));
    	        	}
    	        }
    	    }
    	});
    	
    	sldTime.addMouseListener(new MouseAdapter() {
    		@Override
            public void mousePressed(MouseEvent e) {
            	Point p = e.getPoint();
            	double percent = p.x / ((double) sldTime.getWidth());
            	int range = sldTime.getMaximum() - sldTime.getMinimum();
            	double newVal = range * percent;
            	int result = (int)(sldTime.getMinimum() + newVal);
            	sldTime.setValue(result);
            	myClip.setFramePosition(sldTime.getValue());
            	
            	//取得目前已經播放的秒數和對應的"分:秒"格式
            	playTotalSecs = (int) (myClip.getFramePosition()/audioInputStream.getFrameLength() * totalSeconds);
            	playMinutes = playTotalSecs/60;
            	playSeconds = playTotalSecs%60;
            	//顯示 「播放時間」/「總共時間」
                sldTime.setBorder(BorderFactory.createTitledBorder(playMinutes+":"+playSeconds+" / "+soundMinutes+":"+soundSeconds));
            }
        });
    	
    	//播放音量 控制
    	/*檔案載入時設定之音量最大，最小為減少40db之音量，藉由調整Jslider進行控制*/
    	sldVolume = new JSlider(0,100,0);
    	sldVolume.setBorder(BorderFactory.createTitledBorder("­µ¶q"));
    	sldVolume.setMaximum(0);	//設定最大值
    	sldVolume.setMinimum(-40);	//設定最小值
    	sldVolume.addChangeListener(new ChangeListener(){
    	    public void stateChanged(ChangeEvent e)
    	    {
    	    	gainControl.setValue((float)sldVolume.getValue()) ;
    	    }
    	});
    	
    	sldVolume.addMouseListener(new MouseAdapter() {
    		@Override
            public void mousePressed(MouseEvent e) {
            	Point p = e.getPoint();
            	double percent = p.x / ((double) sldVolume.getWidth());
            	int range = sldVolume.getMaximum() - sldVolume.getMinimum();
            	double newVal = range * percent;
            	int result = (int)(sldVolume.getMinimum() + newVal);
            	sldVolume.setValue(result);
            	gainControl.setValue((float)sldVolume.getValue()) ;
            }
        });
    	
    	
    	
    	
        f = new JFrame("MyFrame");
        f.setLayout(new BorderLayout());
        flg = new FileDialog(f, "¶}±Ò´CÅéÀÉ", FileDialog.LOAD);
        p =  new JPanel(new FlowLayout());
        
        buttonPlay = new JButton("¼½©ñ");
        buttonPause = new JButton("¼È°±");
        buttonStop = new JButton("°±¤î");
        buttonCircle = new JButton("­«½Æ");
        buttonOpen = new JButton("¿ï¾ÜÀÉ®×");
        
        buttonPlay.setActionCommand("buttonPlay");
        buttonPause.setActionCommand("buttonPause");
        buttonStop.setActionCommand("buttonStop");
        buttonCircle.setActionCommand("buttonCircle");
        buttonOpen.setActionCommand("buttonOpen");
        
        buttonPlay.addActionListener(this);
        buttonPause.addActionListener(this);
        buttonCircle.addActionListener(this);
        buttonStop.addActionListener(this);
        buttonOpen.addActionListener(this);
        
        buttonPlay.setEnabled(false);
        buttonPause.setEnabled(false);
        buttonStop.setEnabled(false);
        buttonCircle.setEnabled(false);
        buttonOpen.setEnabled(true);
        
        p.add(buttonPlay);
        p.add(buttonPause);
        p.add(buttonStop);
        p.add(buttonCircle);
        p.add(buttonOpen);

        f.add(p, BorderLayout.SOUTH);
        f.add(sldTime, BorderLayout.NORTH);
        f.add(sldVolume, BorderLayout.CENTER);
        f.pack();
        f.setVisible(true);
        f.setResizable(false);//視窗放大按鈕無效

    }
    

    @SuppressWarnings("deprecation")
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        String cmd = e.getActionCommand();
        int id = -1;
        for (int i = 0; i <strCmd.length; i++)
            if(strCmd[i] == cmd) id=i;
        switch (id) {
            case Option.PLAY:
                myClip.start();
                new Timer(1, new ActionListener(){
 
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        // TODO Auto-generated method stub
                        sldTime.setMaximum((int) audioInputStream.getFrameLength());
                        sldTime.setValue(myClip.getFramePosition());
                        if(sldTime.getValue() == (int) audioInputStream.getFrameLength()){
                        	sldTime.setValue(0);
                            buttonPlay.setEnabled(true);
                        }
                        
                        //取得目前已經播放的秒數和對應的"分:秒"格式
                        playTotalSecs = (int) (sldTime.getValue()/ audioInputStream.getFormat().getSampleRate());
                        playMinutes = playTotalSecs/60;
                        playSeconds = playTotalSecs%60;
                        //顯示 「播放時間」/「總共時間」
                        sldTime.setBorder(BorderFactory.createTitledBorder(playMinutes+":"+playSeconds+" / "+soundMinutes+":"+soundSeconds));
    	                
                    }}).start();
                buttonPlay.setEnabled(false);
                buttonPause.setEnabled(true);
                buttonStop.setEnabled(true);
                break;
            case Option.PAUSE:
                myClip.stop();
                buttonPlay.setEnabled(true);
                buttonPause.setEnabled(false);
                buttonCircle.setEnabled(true);
                break;
            case Option.STOP:
                AudioLoad();
                buttonPlay.setEnabled(true);
                buttonPause.setEnabled(false);
                buttonStop.setEnabled(false);
                buttonCircle.setEnabled(true);
                break;
            case Option.CIRCLE:
                AudioLoad();
                myClip.loop(-1);
                new Timer(1, new ActionListener(){
                	 
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        // TODO Auto-generated method stub
                        sldTime.setMaximum((int) audioInputStream.getFrameLength());
                        sldTime.setValue(myClip.getFramePosition());
                        if(sldTime.getValue() == (int) audioInputStream.getFrameLength()){
                        	sldTime.setValue(0);
                        	myClip.setFramePosition(0);
                        	buttonPlay.setEnabled(true);
                        }
                    }}).start();
                
                buttonPlay.setEnabled(false);
                buttonPause.setEnabled(true);
                buttonStop.setEnabled(true);
                buttonCircle.setEnabled(false);
                break;
            case Option.OPEN:
            	flg.show();
                if(!flg.getFile().equals("null")){
                    AudioLoad();
                    buttonPlay.setEnabled(true);
                    buttonPause.setEnabled(false);
                    buttonStop.setEnabled(false);
                    buttonCircle.setEnabled(true);
                }
                break;
            default:
        }
             
         
    }
}